package com.novel.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import com.novel.common.enums.UserIdentifyEnum;
import com.novel.common.event.DeleteCommentEvent;
import com.novel.common.exception.CustomerException;
import com.novel.common.vo.CommentVo;
import com.novel.mapper.NovelChapterMapper;
import com.novel.mapper.NovelCommentMapper;
import com.novel.mapper.NovelMapper;
import com.novel.pojo.novel.Novel;
import com.novel.pojo.novel.NovelChapter;
import com.novel.pojo.novel.NovelComment;
import com.novel.pojo.system.User;
import com.novel.utils.GsonTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class NovelCommentService {

    @Autowired
    private NovelCommentMapper novelCommentMapper;

    @Autowired
    private NovelChapterMapper novelChapterMapper;

    @Autowired
    private NovelMapper novelMapper;

    @Autowired
    private ApplicationEventPublisher publisher;

    /**
     * 添加评论信息
     */
    @Transactional
    public boolean insertCommentInfo(NovelComment novelComment) {
        return novelCommentMapper.insert(novelComment) == 1;
    }

    /**
     * 删除评论
     * 需要校验是否有权限删除这个条评论
     */
    @Transactional
    public boolean deleteCommentInfoByCommentId(String commentId, User user) {
        //查询评论内容
        NovelComment comment = novelCommentMapper.selectByPrimaryKey(commentId);

        if (!StringUtils.equals(comment.getUserId(), user.getUserId()) &&
                user.getIdentify() == UserIdentifyEnum.READER.getCode()) {
            throw new CustomerException("用户权限不足");
        }

        if (user.getIdentify() == UserIdentifyEnum.AUTHOR.getCode()) {
            //查询小说是谁写的
            Novel novel = novelMapper.selectByPrimaryKey(comment.getNovelId());

            if (!StringUtils.equals(novel.getAuthorId(), user.getUserId())) {
                throw new CustomerException("您不是这本小说做的作者,没有权限删除此评论");
            }
        }

        boolean result = novelCommentMapper.deleteByPrimaryKey(commentId) == 1;

        if (result) {
            DeleteCommentEvent event = new DeleteCommentEvent(this, comment);
            publisher.publishEvent(event);
        }

        return result;
    }


    /**
     * 管理员分页查询评论内容
     */
    public PageInfo<CommentVo> queryCommentByManager(int pageNum, int pageSize) {
        //设置分页参数
        PageHelper.startPage(pageNum, pageSize);

        //查询评论内容
        Example example = new Example(NovelComment.class);
        example.setOrderByClause("created_time desc");
        List<NovelComment> novelCommentList = novelCommentMapper.selectByExample(example);

        //pageInfo只会对上面第一个select做分页相关操作，如果间隔多个就需要属性复制处理
        PageInfo<NovelComment> pageInfo = new PageInfo<>(novelCommentList);
        PageInfo<CommentVo> result = new PageInfo<>();
        pageInfo.setList(Collections.emptyList());
        BeanUtils.copyProperties(pageInfo, result);

        //数据类型转换
        List<CommentVo> commentVoList = novelCommentList.stream().map(CommentVo::convert).collect(Collectors.toList());

        //保存章节id和小说id
        List<String> chapterIds = novelCommentList.stream().map(NovelComment::getChapterId).collect(Collectors.toList());
        List<String> novelIds = novelCommentList.stream().map(NovelComment::getNovelId).collect(Collectors.toList());

        //查询小说信息和章节信息
        //查询章节内容
        Example chapterExample = new Example(NovelChapter.class);
        chapterExample.createCriteria().andIn("chapterId", chapterIds);
        List<NovelChapter> novelChapterList = novelChapterMapper.selectByExample(chapterExample);

        Map<String, String> chapterIdAndChapterMap = Maps.newHashMap();
        novelChapterList.forEach(chapter ->
                chapterIdAndChapterMap.put(chapter.getChapterId(), chapter.getChapterName()));

        //查询小说内容
        Example novelExample = new Example(Novel.class);
        List<Novel> novelList = novelMapper.selectByExample(novelExample);
        novelExample.createCriteria().andIn("novelId", novelIds);
        //转换为 小说id-小说名称map
        Map<String, String> novelIdAndNovelMap = Maps.newHashMap();
        novelList.forEach(novel ->
                novelIdAndNovelMap.put(novel.getNovelId(), novel.getNovelName()));

        //补充数据
        commentVoList.forEach(commentVo -> {
            commentVo.setNovelName(novelIdAndNovelMap.get(commentVo.getNovelId()));
            commentVo.setChapterName(chapterIdAndChapterMap.get(commentVo.getChapterId()));
        });

        result.setList(commentVoList);

        return result;
    }


    /**
     * 作者分页查询评论内容
     */
    public PageInfo<CommentVo> queryCommentByAuthor(int pageNum, int pageSize, String authorId) {
        //查询作者有那些书籍
        Example novelExample = new Example(Novel.class);

        novelExample.createCriteria().andEqualTo("authorId", authorId);
        List<Novel> novelList = novelMapper.selectByExample(novelExample);

        //查询不到作者的书籍，直接返回空
        if (CollectionUtils.isEmpty(novelList)) {
            return new PageInfo<>(Collections.emptyList());
        }

        //转换为 小说id-小说名称map
        Map<String, String> novelIdAndNovelMap = Maps.newHashMap();
        novelList.forEach(novel ->
                novelIdAndNovelMap.put(novel.getNovelId(), novel.getNovelName()));

        List<String> novelIds = novelList.stream().map(Novel::getNovelId).collect(Collectors.toList());

        //设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        //查询评论内容
        Example example = new Example(NovelComment.class);
        example.setOrderByClause("created_time desc");
        example.createCriteria().andIn("novelId", novelIds);
        List<NovelComment> novelCommentList = novelCommentMapper.selectByExample(example);

        //pageInfo只会对上面第一个select做分页相关操作，如果间隔多个就需要属性复制处理
        PageInfo<NovelComment> pageInfo = new PageInfo<>(novelCommentList);
        PageInfo<CommentVo> result = new PageInfo<>();
        pageInfo.setList(Collections.emptyList());
        BeanUtils.copyProperties(pageInfo, result);

        Set<String> chapterIds = novelCommentList.stream().map(NovelComment::getChapterId).collect(Collectors.toSet());

        if (CollectionUtils.isEmpty(chapterIds)) {
            return new PageInfo<>(Collections.emptyList());
        }

        //查询章节内容
        Example chapterExample = new Example(NovelChapter.class);
        chapterExample.createCriteria().andIn("chapterId", chapterIds);
        List<NovelChapter> novelChapterList = novelChapterMapper.selectByExample(chapterExample);

        Map<String, String> chapterIdAndChapterMap = Maps.newHashMap();
        novelChapterList.forEach(chapter ->
                chapterIdAndChapterMap.put(chapter.getChapterId(), chapter.getChapterName()));


        List<CommentVo> commentVoList = novelCommentList.stream().map(CommentVo::convert).collect(Collectors.toList());

        commentVoList.forEach(commentVo -> {
            commentVo.setNovelName(novelIdAndNovelMap.get(commentVo.getNovelId()));
            commentVo.setChapterName(chapterIdAndChapterMap.get(commentVo.getChapterId()));
        });

        result.setList(commentVoList);

        return result;
    }

    /**
     * 分页查询评论内容
     */
    public PageInfo<NovelComment> queryCommentByPage(int pageNum, int pageSize, String novelId, String chapterId, String userId) {
        PageHelper.startPage(pageNum, pageSize);

        Example example = new Example(NovelComment.class);
        example.createCriteria()
                .andEqualTo("userId", userId)
                .andEqualTo("novelId", novelId)
                .andEqualTo("chapterId", chapterId);
        return new PageInfo<>(novelCommentMapper.selectByExample(example));
    }

}